home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 10888 < prev    next >
Encoding:
Text File  |  1996-08-05  |  5.0 KB  |  162 lines

  1. Newsgroups: comp.lang.c++
  2. Path: netcom.com!marnold
  3. From: marnold@netcom.com (Matt Arnold)
  4. Subject: Re: "Deep" Destructor Query
  5. Message-ID: <marnoldDo19rI.n0A@netcom.com>
  6. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  7. References: <826257180snz@pbutler.demon.co.uk>
  8. Date: Sun, 10 Mar 1996 03:59:42 GMT
  9. Sender: marnold@netcom20.netcom.com
  10.  
  11. Peter Hugh Butler <Peter@pbutler.demon.co.uk> writes:
  12.  
  13. >I have two questions, hope nobody minds.  Please answer by e-mail, unless
  14. >you think that the group would benefit from the answer.
  15.  
  16. >I have read the FAQ on this subject, but I am still a little confused.
  17. >(By the way, I know I should use a dynamic multi-dimensional array, but I
  18. >just wanted to try it this way).
  19.  
  20. >Destructors
  21.  
  22. >I have two classes, one instantiated in the other.  One (shape) contains a
  23. >dynamic array of structs, the other (object) contains a dynamic array of 
  24. >shapes.  Declared sort of like this:
  25.  
  26. >struct point
  27. >{
  28. >int x, y, z;
  29. >};
  30.  
  31. >Class Shape
  32. >{
  33. >private:
  34. >point *p;  //dynamic array of points
  35. >//...etc
  36. >};
  37.  
  38. >Class Object
  39. >{
  40. >private:
  41. >int numshapes;  //number of data elements
  42. >shape *shapes;  //dynamic array of shapes
  43. >//etc...
  44. >};
  45.  
  46. >Now, this all works quite well, apart from when it comes to destructor
  47. >functions.  For shape I have:
  48.  
  49. >Shape::~Shape()
  50. >{
  51. >if (p)
  52. >        delete [] p;
  53. >}
  54.  
  55. >which works ok.  But when I wrote a destructor for Object, like this:
  56.  
  57. >Object::~Object()
  58. >{
  59. >for (int i = 0; i < numshapes; i++)
  60. >        shapes[i].~shape();  //"Deep" destructor, deletes underlying arrays.
  61.  
  62. >delete [] shapes;  //delete the array of pointers
  63. >}
  64.  
  65. This is wrong, you don't have an array of pointers to shape objects, you 
  66. have an array of shape objects (got back and look at your declaration for 
  67. the shapes member).
  68.  
  69. It should be...
  70.  
  71.   shape **shapes;
  72.  
  73. ...instead of...
  74.  
  75.   shape *shapes;
  76.  
  77. ...(note the extra asterisk).
  78.  
  79. In your code, as it is, when you do "delete [] shapes" you are asking the
  80. compiler to generate code that deletes an array of shape *objects*, not
  81. pointers to shape objects.  Since your array is not an array of shape 
  82. objects themselves, just pointers to them, this generated code dies a
  83. horrible GPF death, as it tries to treat a chunk of memory as an array of
  84. shape objects and call shape::~shape() for each element.
  85.  
  86. >The program causes a General Protection Fault (guess which OS I'm using and 
  87. >win a cookie).  It fails when it tries to delete the array of null pointers
  88. >pointed to by shape.  It works when I leave the "delete [] shapes;" line out.
  89.  
  90. >Well, I have two questions:
  91.  
  92. >1) If I simply "delete [] shapes" with no loop to delete the arrays underneath,
  93. >   will the ~shape() destructor be automatically called, thus deleting the
  94. >   shape objects correctly?  I wouldn't think so, but it would be good to be
  95. >   corrected.
  96.  
  97. No, it won't.  But, as I've already explained, you code has a big mistake in
  98. it, so your starting assumptions are a little off.
  99.  
  100.  
  101. Rewrite Object like this...
  102.  
  103.  
  104. Class Object
  105. {
  106. private:
  107. int numshapes;  //number of data elements
  108. shape **shapes;  //dynamic array of shape POINTERS!!
  109. //etc...
  110. };
  111.  
  112. Object::~Object()
  113. {
  114. for (int i = 0; i < numshapes; i++)
  115.           shapes[i]->~shape();  // destroy via POINTER 
  116. delete [] shapes;  //delete the array of POINTERS
  117. }
  118.  
  119. ..and things should start working.
  120.  
  121. >2) If I delete each shape with a loop (as above), does this mean that shapes
  122. >   pointer points to nothing?  I would have thought that it would point to
  123. >   an array of null pointers.
  124.  
  125. No.  Well, first you didn't have an array of pointers, but I hope you see 
  126. your mistake now.
  127.  
  128. To answer you question in general, deleting an object pointed to by some
  129. pointer variable DOES NOTHING to the pointer variable itself (pointers 
  130. are no automatically nulled-out by delete).
  131.  
  132.   shape* p = new shape();  
  133.  
  134.   // here, p contains the value of some address
  135.  
  136.   delete p;
  137.  
  138.   // here, p still contains the same address, not null, even though the 
  139.   // shape it pointed to has been destroyed.....yes, p certainly contains 
  140.   // an invalid address, but not null
  141.  
  142. The same goes for an array of shape pointers.  Just because you delete
  143. each shape in it, doesn't make each array element null.  The array is 
  144. still full of pointer values, all of them now invalid.
  145.  
  146.  
  147. A final note, if you are doing a lot of work with dynamic arrays, you 
  148. might want to look into using the Standard Template Library (STL).  It 
  149. contains a nice template class called vector, which acts like a normal 
  150. array, but can resize itself dynamically.  The STL vector class is 
  151. already coded, tested and ready for you to use.
  152.  
  153.  
  154. Regards,
  155. -------------------------------------------------------------------------
  156. Matt Arnold                       |        | ||| | |||| |  | | || ||
  157. marnold@netcom.com                |        | ||| | |||| |  | | || ||
  158. Boston, MA                        |      0 | ||| | |||| |  | | || ||
  159. 617.389.7384 (h) 617.576.2760 (w) |        | ||| | |||| |  | | || ||
  160. C++, MIDI, Win32/95 developer     |        | ||| 4 3 1   0 8 3 || ||
  161. -------------------------------------------------------------------------
  162.